/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 * \file
 * \brief Utilities for HubCtrl.
 * \author Antti Maula <antti.maula@tkk.fi>
 */
#include "hubctrl_utils.h"
#include "protocolDispatcher.h"
#include "fastProtocolHdr.h"
#include "hubctrlHdr.h"
#include "hubctrl_common.h"
#include "apsecurity.h"
#include "owndebug.h"
#include "ownutils.h"
#include "msgreplybuffer.h"
#include <assert.h>

//*****************************************************************************
//*****************************************************************************
static unsigned int gMessageSequence = 0;
static TMsgReplyBuffer gMessageReplyBuffer;
static THubCtrl *gHubCtrlInstance = NULL;
//*****************************************************************************
//*****************************************************************************

void hubctrlutils_Init(THubCtrl *aHubCtrlInstance)
{
  msgreplybufferInit(&gMessageReplyBuffer);
  gHubCtrlInstance = aHubCtrlInstance;
}
//*****************************************************************************

void hubctrlutils_Deinit()
{
  msgreplybufferDeinit(&gMessageReplyBuffer);
  gHubCtrlInstance = NULL;
}
//*****************************************************************************

int hubctrlutils_RequestRegisterAP(TConnectionList *list, TConnectionListEntry *entry,
                                   const unsigned int aRequestedAPId)
                                   
{
  assert(gHubCtrlInstance != NULL);

  const unsigned int totsize = ( sizeof(THubCtrlProtocolHeader) + 
                                 sizeof(THubCtrlSubHeaderRegisterAP) + 
                                 sizeof(THubCtrlSubHeaderAuthentication) );
  uint8_t buffer[totsize];
  THubCtrlProtocolHeader *frame = (THubCtrlProtocolHeader *)buffer;
  THubCtrlSubHeaderRegisterAP *rap = (THubCtrlSubHeaderRegisterAP *)(frame+1);
  THubCtrlSubHeaderAuthentication *auth = (THubCtrlSubHeaderAuthentication *)(rap+1);
  
  //double begin = ownTime_get_s();
  // Assign identification information
  protocolIdentificationConstructHeader(&frame->protocol_id,
                                        HUBCTRLPROTOCOL_NUMBER,
                                        totsize);
  
  // Assign base parameters
  frame->request = KHubCtrlRequestRegisterAP;
  frame->flags = 0x00;
  frame->subheader_count = 2;
  frame->result = 0;
  frame->message_id = ++gMessageSequence;
  
  // Assign Request parameter
  rap->subtype = KHubCtrlSubtypeRegisterAP;
  rap->subsize = sizeof(THubCtrlSubHeaderRegisterAP);
  rap->peer_id = aRequestedAPId;

  // Assign authentication data
  auth->subtype = KHubCtrlSubtypeAuthentication;
  auth->subsize = sizeof(THubCtrlSubHeaderAuthentication);
  memset(auth->sha1, 0x00, sizeof(auth->sha1));
  auth->timestamp_s = time(NULL);
         
  // Now; calculate authentication data SHA-1; via separate buffer.
  uint8_t sha1[20];
  unsigned int sha1_size = 20;
  apsecurityCalculateHMAC(sha1,
                          &sha1_size,
                          (uint8_t*)gHubCtrlInstance->ap2ap_secret,
                          gHubCtrlInstance->ap2ap_secret_size,
                          buffer,
                          totsize);
  assert(sha1_size == 20);
  memcpy(auth->sha1, sha1, sizeof(sha1));


  // Complete. SEND!
  //r = msgreplybufferInsertMsg(&gMessageReplyBuffer, gMessageSequence, NULL);
  //assert(r == 0);

  connectionListSendRawDataByEntry(list, (void*)buffer, totsize, entry);
  //  protocolDispSendPacket(link, (void*)frame, totsize);

  return 0;
}
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
